﻿using Microsoft.AspNetCore.Http;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;

namespace Common.Helper
{
    public class JwtHelper
    {
        /// <summary>
        /// 颁发 Jwt 字符串
        /// </summary>
        /// <param name="tokenModel"></param>
        /// <returns></returns>
        public static string IssueJwt(TokenModelJwt tokenModel)
        {
            string iss = AppSettings.App(new string[] { "Audience", "Issuer" });
            string aud = AppSettings.App(new string[] { "Audience", "Audience" });
            string secret = AppSettings.App(new string[] { "Audience", "Secret" });

            var nbf = new DateTimeOffset(DateTime.Now).ToUnixTimeMilliseconds();
            var iat = nbf;
            var exp = new DateTimeOffset(DateTime.Now.AddSeconds(1000)).ToUnixTimeMilliseconds();
            var expiration = DateTime.Now.AddSeconds(1000);

            var claims = new List<Claim>
            {
                new Claim(JwtRegisteredClaimNames.Jti,tokenModel.Uid.ToString()),
                new Claim(JwtRegisteredClaimNames.Iat,$"{iat}"),
                new Claim(JwtRegisteredClaimNames.Nbf,$"{nbf}"),
                new Claim(JwtRegisteredClaimNames.Exp,$"{exp}"),
                new Claim(ClaimTypes.Expiration,expiration.ToString() ),
                new Claim(JwtRegisteredClaimNames.Iss, iss),
                new Claim(JwtRegisteredClaimNames.Aud, aud),
            };

            // 可以将一个用户多个角色全部赋予
            claims.AddRange(tokenModel.Role.Split(',').Select(s=>new Claim(ClaimTypes.Role,s)));
            // 密钥
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret));
            var creds = new SigningCredentials(key,SecurityAlgorithms.HmacSha256);
            var jwt = new JwtSecurityToken(iss, aud,claims,DateTime.Now, expiration, creds);
            var jwtHandler = new JwtSecurityTokenHandler();
            var encodedJwt = jwtHandler.WriteToken(jwt);

            return encodedJwt;
        }

        /// <summary>
        /// 解析 token
        /// </summary>
        /// <param name="jwtStr"></param>
        /// <returns></returns>
        public static TokenModelJwt SerializeJwt(string jwtStr)
        {
            var jwtHandler = new JwtSecurityTokenHandler();
            TokenModelJwt tokenModelJwt = new TokenModelJwt();

            // 校验 token
            if (!string.IsNullOrEmpty(jwtStr) && jwtHandler.CanReadToken(jwtStr))
            {
                var jwtToken = jwtHandler.ReadJwtToken(jwtStr);
                object role;
                jwtToken.Payload.TryGetValue(ClaimTypes.Role, out role);
                tokenModelJwt = new TokenModelJwt
                {
                    Uid = Convert.ToInt32(jwtToken.Id),
                    Role = role == null ? "" : role.ToString()
                };
            }
            return tokenModelJwt;
        }
        /// <summary>
        /// 授权解析 jwt
        /// </summary>
        /// <param name="httpContext"></param>
        /// <returns></returns>
        public static TokenModelJwt ParsingJwtToken(HttpContext httpContext)
        {
            if (!httpContext.Request.Headers.ContainsKey("Authorization"))
                return null;
            var tokenHeader = httpContext.Request.Headers["Authorization"].ToString().Replace("Bearer ", "");
            TokenModelJwt jwt = SerializeJwt(tokenHeader);
            return jwt;
        }
    }

    public class TokenModelJwt
    {
        /// <summary>
        /// Id
        /// </summary>
        public int Uid { get; set; }
        /// <summary>
        /// 角色
        /// </summary>
        public string Role { get; set; }
        /// <summary>
        /// 职能
        /// </summary>
        public string Work { get; set; }
    }
}
